/*
 * EditForm.cs - Wordtrainer
 * 
 * Copyright (C) 1998-2008 Markus Kilås
 *               
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 *
 * Authors:
 *   Markus Kilås <markus@markuspage.com>
 */

using System;
using Gtk;
using Mono.Unix;

namespace WtSharp
{
	
	
	public partial class EditForm : Gtk.Bin
	{
		private WtDocument m_document;
		private TreeStore store;
		private Gdk.Pixbuf pixbufMarkS;
		private Gdk.Pixbuf pixbufMarkV;

		private bool m_bChangingWord = false; // If we are changeing or adding a new word
		
		private MainWindow mainWindow;
		private SpecialCharacters m_SpecialChars;
		
		public EditForm(MainWindow parent, WtSettings settings, SpecialCharacters specialChars)
		{
			mainWindow = parent;
			m_SpecialChars = specialChars;
			this.Build();
			
			// Load marks
			pixbufMarkS = Gdk.Pixbuf.LoadFromResource("mark-s.png").ScaleSimple(16,16,Gdk.InterpType.Bilinear);
			pixbufMarkV = Gdk.Pixbuf.LoadFromResource("mark-v.png").ScaleSimple(16,16,Gdk.InterpType.Bilinear);
			
			// TreeView
			store = new TreeStore (typeof (WtWord), typeof (Gdk.Pixbuf), typeof(string), typeof(string));
			treeview2.Model = store;
			treeview2.HeadersVisible = true;
			treeview2.HeadersClickable = true;
			
			// TreeView columns
			treeview2.AppendColumn(Catalog.GetString("Type"), new CellRendererPixbuf(), "pixbuf", 1);
			treeview2.AppendColumn(Catalog.GetString("Foreign word"), new CellRendererText(), "text", 2);
			treeview2.AppendColumn(Catalog.GetString("Translation"), new CellRendererText(), "text", 3);
			treeview2.ColumnsAutosize();
			treeview2.Columns[1].MinWidth = 280;
			treeview2.Columns[1].Resizable = true;
			treeview2.Columns[1].Clickable = true;
			treeview2.Columns[2].Clickable = true;
			treeview2.Columns[1].Clicked += OnEditColumn1ClickedEvent;
			treeview2.Columns[2].Clicked += OnEditColumn2ClickedEvent;
			
			// Event handlers
			entryWordF.KeyPressEvent += OnSpecialKeyPressEvent;
			entryWordT.KeyPressEvent += OnSpecialKeyPressEvent;

			// Settings
			UpdateSpecialCharactersButtons();
			
			ResetInput();
		}
		
		public void Activated()
		{
			entryWordF.GrabFocus();
		}
		
		public void DocumentChanged(WtDocument document)
		{
			m_document = document;
			UpdateTitles();
			populateList();
			ResetInput();
		}

		private void populateList()
		{
			store.Clear();
			
			if(checkbuttonSort.Active)
				m_document.Words.Sort();
			
			Gdk.Pixbuf pixbuff = null;
			foreach(WtWord word in m_document.Words)
		    {
				if(word.Type == 1)
					pixbuff = pixbufMarkS;
				else if(word.Type == 2)
					pixbuff = pixbufMarkV;
				else
					pixbuff = null;
				store.AppendValues (word, pixbuff, word.WordF, word.WordT);
		    }
			treeview2.Model = store;
			
			LabelEditNumWords.Text = Catalog.GetString("Number of words: ")+m_document.Words.Count;
		}
		
		protected virtual void OnTreeview2RowActivated (object o, Gtk.RowActivatedArgs args)
		{
			int index = args.Path.Indices[0];
			WtWord word = (WtWord)m_document.Words[index];
			entryWordF.Text = word.WordF;
			entryWordT.Text = word.WordT;
			combobox2.Active = word.Type;
			buttonAdd.Label = Catalog.GetString("Apply");
			buttonDelete.Sensitive = true;
			m_bChangingWord = true;
			entryWordF.GrabFocus();
		}

		public void MenuEditAddActivated()
		{
			if(entryWordF.Text.Length < 1)
				entryWordF.GrabFocus();
			else if(entryWordT.Text.Length < 1)
				entryWordT.GrabFocus();
			else
			{
				WtWord word;
				if(m_bChangingWord) 
				{
					int index = treeview2.Selection.GetSelectedRows()[0].Indices[0];
					word = (WtWord)m_document.Words[index];
					word.WordF = entryWordF.Text;
					word.WordT = entryWordT.Text;
					word.Type = combobox2.Active;
					populateList();
				}
				else // Adding word
				{
					word = new WtWord(entryWordF.Text, entryWordT.Text);
					word.Type = combobox2.Active;
					m_document.Words.Add(word);
					populateList();
					
					TreePath sel = new TreePath(new int[]{m_document.Words.IndexOf(word)});
					treeview2.Selection.SelectPath(sel);
					treeview2.ScrollToCell(sel, null, false, 0, 0);
				}
				
				mainWindow.DocumentChanged(true);
				
				ResetInput();
			}
		}
		
		private void ResetInput()
		{
			buttonAdd.Label = Catalog.GetString("Add");
			entryWordF.Text = "";
			entryWordT.Text = "";
			combobox2.Active = 0;
			m_bChangingWord = false;
			buttonDelete.Sensitive = false;
			entryWordF.GrabFocus();
		}
		
		public void MenuEditNewActivated()
		{
			ResetInput();
		}

		public void MenuEditDeleteActivated()
		{
			TreePath[] paths = treeview2.Selection.GetSelectedRows();
			if(paths.Length < 1)
				return;
		
			int index = paths[0].Indices[0];
			
			m_document.Words.RemoveAt(index);
			mainWindow.DocumentChanged(true);
			populateList();
			ResetInput();
		}

		protected virtual void OnEntryWordFActivated (object sender, System.EventArgs e)
		{
			entryWordT.GrabFocus();
		}

		protected virtual void OnEntryWordTActivated (object sender, System.EventArgs e)
		{
			if(entryWordF.Text.Length < 1)
				entryWordF.GrabFocus();
			else
				MenuEditAddActivated();
		}
		
		private void UpdateTitles() 
		{
			treeview2.Columns[1].Title = m_document.TitleForeign;
			treeview2.Columns[2].Title = m_document.TitleTranslation;
		}
		
		protected virtual void OnEditColumn1ClickedEvent(object o, EventArgs args)
		{
			mainWindow.SetToolbarText1("");
			TitleDialog dlg = new TitleDialog(mainWindow, m_document.TitleForeign, true);
			dlg.Run();
			string newTitle = dlg.SelectedTitle;
			if(newTitle != null)
			{
				m_document.TitleForeign = newTitle;
				UpdateTitles();
			}
			entryWordF.GrabFocus();
		}
		
		protected virtual void OnEditColumn2ClickedEvent(object o, EventArgs args)
		{
			mainWindow.SetToolbarText1("");
			TitleDialog dlg = new TitleDialog(mainWindow, m_document.TitleTranslation, false);
			dlg.Run();
			string newTitle = dlg.SelectedTitle;
			if(newTitle != null)
			{
				m_document.TitleTranslation = newTitle;
				UpdateTitles();
			}
			entryWordF.GrabFocus();
		}
		
		protected virtual void OnSpecialKeyPressEvent (object o, Gtk.KeyPressEventArgs args)
		{	
			m_SpecialChars.SpecialKeyPressed(o, args);
		}

		protected virtual void OnCheckbuttonSortClicked (object sender, System.EventArgs e)
		{
			populateList();
			entryWordF.GrabFocus();
		}

		public void MenuEditFindActivated()
		{
			mainWindow.SetToolbarText1("");
			FindDialog dlg = new FindDialog(mainWindow);
			dlg.Run();
			string term = dlg.SearchTerm;	
			if(term == null)
			{
				entryWordF.GrabFocus();
				return;
			}
			for(int i = 0; i < m_document.Words.Count; i++)
			{
				WtWord word = (WtWord)m_document.Words[i];
				if(word.WordF.IndexOf(term) != -1 || word.WordT.IndexOf(term) != -1)
				{
					TreePath sel = new TreePath(new int[]{i});
					treeview2.Selection.SelectPath(sel);
					treeview2.ScrollToCell(sel, null, false, 0, 0);
					treeview2.GrabFocus();
					return;
				}
			}
			
			MessageDialog md = new MessageDialog (mainWindow, 
	                                      DialogFlags.DestroyWithParent,
				                          MessageType.Warning, 
	                                      ButtonsType.Ok, Catalog.GetString("Can't find the word."));
			md.Run();
			md.Destroy();
			entryWordF.GrabFocus();
		}

		protected virtual void OnEditSpecial1Clicked (object sender, System.EventArgs e)
		{
			//if(toolbarRadioButtonEdit.Active)
				mainWindow.SetToolbarText1("");

			m_SpecialChars.MessageBox1();
			
			//if(toolbarRadioButtonEdit.Active)
				entryWordF.GrabFocus();
			//else if(toolbarRadioButtonPractise.Active)
			//	practiseForm.AnswerGrabFocus();
		}

		protected virtual void OnEditSpecial2Clicked (object sender, System.EventArgs e)
		{
			//if(toolbarRadioButtonEdit.Active)
				mainWindow.SetToolbarText1("");
			
			m_SpecialChars.MessageBox2();
			
			//if(toolbarRadioButtonEdit.Active)
				entryWordF.GrabFocus();
			//else if(toolbarRadioButtonPractise.Active)
			//	practiseForm.AnswerGrabFocus();
		}

		protected virtual void OnEditSpecial3Clicked (object sender, System.EventArgs e)
		{
			//if(toolbarRadioButtonEdit.Active)
				mainWindow.SetToolbarText1("");
			
			m_SpecialChars.MessageBox3();
			
			//if(toolbarRadioButtonEdit.Active)
				entryWordF.GrabFocus();
			//else if(toolbarRadioButtonPractise.Active)
			//	practiseForm.AnswerGrabFocus();
		}

		protected virtual void OnEditSpecial4Clicked (object sender, System.EventArgs e)
		{
			//if(toolbarRadioButtonEdit.Active)
				mainWindow.SetToolbarText1("");

			m_SpecialChars.MessageBox4();
			
			//if(toolbarRadioButtonEdit.Active)
				entryWordF.GrabFocus();
			//else if(toolbarRadioButtonPractise.Active)
			//	practiseForm.AnswerGrabFocus();
		}

		public void MenuEditImportActivated()
		{
			mainWindow.SetToolbarText1("");
			FileChooserDialog fc = mainWindow.CreateOpenDialog();
			
			if(fc.Run() == (int)ResponseType.Accept)
			{				
				IFileHandler fileHandler = FileHandlerFactory.Instance.GetFileHandler(fc.Filename, fc.Filter);
				WtDocument doc = fileHandler.Open(fc.Filename);
				ImportDialog dlg = new ImportDialog(mainWindow, doc.Words, fc.Filename);
				fc.Destroy();
				dlg.Run();
				if(dlg.SelectedWords != null)
				{
					Console.WriteLine("TODO: Check duplicates");
					/////////////TODO: Message
					// x new words have been added.
					// The following words was already in the list:
					// word1
					// word2
					// ...
					m_document.Words.AddRange(dlg.SelectedWords);
					MessageDialog md = new MessageDialog (mainWindow, 
	                                      DialogFlags.DestroyWithParent,
				                          MessageType.Info, 
	                                      ButtonsType.Ok, dlg.SelectedWords.Count+Catalog.GetString(" words imported."));
					md.Run();
					md.Destroy();
					populateList();
				}
				doc.Close();
			}
			else
				fc.Destroy();
			
			entryWordF.GrabFocus();
		}
		
		protected virtual void OnEntryWordFFocusInEvent (object o, Gtk.FocusInEventArgs args)
		{
			if(m_bChangingWord)
				mainWindow.SetToolbarText1(Catalog.GetString("Change the word and then press ENTER"));
			else
				mainWindow.SetToolbarText1(Catalog.GetString("Write the foreign word and press ENTER"));
		}

		protected virtual void OnEntryWordTFocusInEvent (object o, Gtk.FocusInEventArgs args)
		{
			if(m_bChangingWord)
				mainWindow.SetToolbarText1(Catalog.GetString("Change the word and then press ENTER"));
			else
				mainWindow.SetToolbarText1(Catalog.GetString("Write the translation and press ENTER"));
		}

		protected virtual void OnCombobox2Changed (object sender, System.EventArgs e)
		{
			entryWordF.GrabFocus();
		}

		protected virtual void OnCombobox2FocusChildSet (object o, Gtk.FocusChildSetArgs args)
		{
			mainWindow.SetToolbarText1(Catalog.GetString("Select part of speech from the list"));
		}

		protected virtual void OnTreeview2FocusInEvent (object o, Gtk.FocusInEventArgs args)
		{
			mainWindow.SetToolbarText1(Catalog.GetString("Press ENTER to change the word"));
		}
		
		protected virtual void OnButtonEditFindClicked (object sender, System.EventArgs e)
		{
			MenuEditFindActivated();
		}

		protected virtual void OnButtonEditImportClicked (object sender, System.EventArgs e)
		{
			MenuEditImportActivated();
		}

		protected virtual void OnButtonDeleteClicked (object sender, System.EventArgs e)
		{
			MenuEditDeleteActivated();
		}

		protected virtual void OnButtonNewWordClicked (object sender, System.EventArgs e)
		{
			MenuEditNewActivated();
		}

		protected virtual void OnButtonAddClicked (object sender, System.EventArgs e)
		{
			MenuEditAddActivated();
		}

		private void UpdateSpecialCharactersButtons()
		{
			EditSpecial1.Label = m_SpecialChars.Label1;
			EditSpecial2.Label = m_SpecialChars.Label2;
			EditSpecial3.Label = m_SpecialChars.Label3;
			EditSpecial4.Label = m_SpecialChars.Label4;
		}
		
	}
}
